﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Web.Security;

using ERPStore.Extensions;
using ERPStore.Web.Extensions;

namespace ERPStore.Web.Security
{
	public class Authentication
	{
		public static List<string> AuthenticatePathExcludedList
		{
			get
			{
				return new List<string>() 
				{
					"/images",
					"/content",
					"/scripts",
					"/services",
					"/favicon.ico",
					"/api/",
					"/realtime",
					"/bundle",
				};
			}
		}


		public static void AuthenticateRequest(System.Web.HttpContext ctx)
		{
			if (AuthenticatePathExcludedList.Any(i => ctx.Request.RawUrl.ToLower().StartsWith(i)))
			{
				return;
			}

			var isNewVisitor = false;
			var visitorId = ctx.GetOrCreateVisitorId(out isNewVisitor);
			var principal = new ERPStore.Models.UserPrincipal(visitorId);
			ctx.User = principal;

			var authCookie = ctx.Request.Cookies[FormsAuthentication.FormsCookieName];
			if (authCookie == null)
			{
				return;
			}

			var logger = GlobalConfiguration.Configuration.DependencyResolver.GetService<ERPStore.Logging.ILogger>();
			var authenticationService = GlobalConfiguration.Configuration.DependencyResolver.GetService<ERPStore.Services.IAccountService>();

			logger.Debug("RequestAuthenticated {0}", ctx.Request.Url);
			// Extraction et decryptage du ticket d'autentification
			FormsAuthenticationTicket authTicket = null;
			try
			{
				authTicket = FormsAuthentication.Decrypt(authCookie.Value);
			}
			catch (Exception ex)
			{
				ex.Data.Add("UserAgent", ctx.Request.UserAgent);
				ex.Data.Add("IP", ctx.Request.UserHostAddress);
				logger.Warn(ex.Message);
			}

			if (authTicket == null)
			{
				return;
			}

			// Recuperation du userId
			int userId = 0;

			int.TryParse(authTicket.Name, out userId);

			if (userId > 0)
			{
				// Creation d'une nouvelle identité
				var id = new FormsIdentity(authTicket);

				// On passe l'identité et les roles a l'objet Principal
				principal = new ERPStore.Models.UserPrincipal(id, visitorId);
				var user = authenticationService.GetUserById(userId);
				if (user != null)
				{
					if (!user.LastLoginDate.HasValue)
					{
						user.LastLoginDate = DateTime.UtcNow;
					}
					principal.CurrentUser = user;
					logger.Debug("User : {0} Logged", principal.CurrentUser.FullName);
				}
				else
				{
					principal = new ERPStore.Models.UserPrincipal(visitorId);
					FormsAuthentication.SignOut();
				}
				ctx.User = principal;
			}

		}
	}
}
